<html>
<head>
<title>WebSocket Chat</title>
<script type="text/javascript">
    if (!window.WebSocket)
        alert("WebSocket not supported by this browser");

    function $() {
        return document.getElementById(arguments[0]);
    }
    function $F() {
        return document.getElementById(arguments[0]).value;
    }

    function getKeyCode(ev) {
        if (window.event)
            return window.event.keyCode;
        return ev.keyCode;
    }
    
    var room = {
        join : function(name) {
            this._username = name;
            var location = "ws://" + window.location.hostname + ":" + window.location.port;
            this._ws = new WebSocket(location);
            this._ws.onopen = this._onopen;
            this._ws.onmessage = this._onmessage;
            this._ws.onclose = this._onclose;
            this._ws.onerror = this._onerror;
        },

        chat : function(text) {
            if (text != null && text.length > 0)
                room._send(room._username, text);
        },

        _onopen : function() {            
            $('join').className = 'hidden';
            $('joined').className = '';
            $('phrase').focus();
            room._send(room._username, 'has joined!');
        },

        _onmessage : function(m) {
            if (m.data) {
                var c = m.data.indexOf(':');
                var from = m.data.substring(0, c).replace('<', '&lt;').replace(
                        '>', '&gt;');
                var text = m.data.substring(c + 1).replace('<', '&lt;')
                        .replace('>', '&gt;');

                var chat = $('chat');
                var spanFrom = document.createElement('span');
                spanFrom.className = 'from';
                spanFrom.innerHTML = from + ':&nbsp;';
                var spanText = document.createElement('span');
                spanText.className = 'text';
                spanText.innerHTML = text;
                var lineBreak = document.createElement('br');
                chat.appendChild(spanFrom);
                chat.appendChild(spanText);
                chat.appendChild(lineBreak);
                chat.scrollTop = chat.scrollHeight - chat.clientHeight;
            }
        },

        _onclose : function(m) {
            this._ws = null;
            $('join').className = '';
            $('joined').className = 'hidden';
            $('username').focus();
            $('chat').innerHTML = '';
        },

        _onerror : function(e) {
            alert(e);
        },
        
        _send : function(user, message) {
            user = user.replace(':', '_');
            if (this._ws)
                this._ws.send(user + ':' + message);
        }
    };
</script>
<style type='text/css'>
div {
    border: 0px solid black;
}

div#chat {
    clear: both;
    width: 40em;
    height: 20ex;
    overflow: auto;
    background-color: #f0f0f0;
    padding: 4px;
    border: 1px solid black;
}

div#input {
    clear: both;
    width: 40em;
    padding: 4px;
    background-color: #e0e0e0;
    border: 1px solid black;
    border-top: 0px
}

input#phrase {
    width: 30em;
    background-color: #e0f0f0;
}

input#username {
    width: 14em;
    background-color: #e0f0f0;
}

div.hidden {
    display: none;
}

span.from {
    font-weight: bold;
}
</style>
</head>
<body>
    <div id="chat"></div>
    <div id="input">
        <div id="join">
            Username:&nbsp;
            <input id="username" type="text" /><input id="joinB"
                class="button" type="submit" name="join" value="Join" />
        </div>
        <div id="joined" class="hidden">
            Chat:&nbsp;<input id="phrase" type="text" /> <input id="sendB"
                class="button" type="submit" name="join" value="Send" />
        </div>
    </div>
    
    <script type="text/javascript">    
        // 1) When user is NOT connected, 'join' div is displayed with Username input + Join button
        $('username').setAttribute('autocomplete', 'OFF');
        // Enter in the username field, opens Chat WebSockets
        $('username').onkeyup = function(ev) {
            var keyc = getKeyCode(ev);
            if (keyc == 13 || keyc == 10) {
                room.join($F('username'));
                return false;
            }
            return true;
        };
        // "Join" button click opens Chat WebSockets
        $('joinB').onclick = function(event) {
            room.join($F('username'));
            return false;
        };
        
        // 2) When user is connected, 'phrase' div is displayed with Chat input + Send button        
        $('phrase').setAttribute('autocomplete', 'OFF');
        // Enter in the 'phrase' field send the message
        $('phrase').onkeyup = function(ev) {
            var keyc = getKeyCode(ev);
            if (keyc == 13 || keyc == 10) {
                room.chat($F('phrase'));
                $('phrase').value = '';
                return false;
            }
            return true;
        };
        // "Send" button click send the message
        $('sendB').onclick = function(event) {
            room.chat($F('phrase'));
            $('phrase').value = '';
            return false;
        };
    </script>
        
</body>
</html>
